package framework.core
{
import com.greensock.TweenMax;

import flash.events.EventDispatcher;
import flash.utils.Dictionary;

import framework.utils.BitmapUtil;
import framework.view.components.graphics.Asset;
import framework.view.components.graphics.Image;
import framework.view.components.graphics.SWF;
import framework.view.components.graphics.asset_ns;

import mx.utils.UIDUtil;

/**
 * AssetsManager
 * @author jliang
 * 
 */
public class AssetsManager
{
	public static var TYPE_BITMAP:String = "bitmap";	
	public static var TYPE_SWF:String = "swf";
	
	private static var tweener:EventDispatcher = new EventDispatcher();
	
	private static var bitmaps:Dictionary = new Dictionary(true); /* BitmapCache */
	
	private static var swfs:Dictionary = new Dictionary(true); /* SWFCache */
	
	public static function loadAsset(url:String, onComplete:Function = null, onError:Function = null, mode:String = "single"):Asset
	{
        if (url == null || url == "")
        {
            url = "url_unknown";
        }
		if (url.indexOf(".swf") > 0)
		{
			return loadSWFAsset(url, mode, onComplete, onError);
		}
		else
		{
			return loadBitmapAsset(url, onComplete, onError);
		}
	}
		
	public static function loadBitmapAsset(url:String, onComplete:Function = null, onError:Function = null):Asset
	{
		var cache:BitmapCache = bitmaps[url];
		var asset:Asset = createAsset(TYPE_BITMAP, onComplete, onError);
		asset.url = url;
		
		if (cache)
		{
			cache.addQueen(asset);
			TweenMax.to(tweener, 0.02, {onCompleteParams: [ cache ], 
										onComplete: function():void{
											if (cache.isLoaded)
											{
												cache.complete();
											}
											else if (cache.isError)
											{
												cache.error();
											}
										}});
			return asset;
		}

		cache = new BitmapCache();
		cache.id = url;
		bitmaps[cache.id] = cache;
		
		cache.addQueen(asset);
		
		var temp:Asset = createAsset(TYPE_BITMAP, bitmapLoadedHandler, bitmapLoadFailHandler);
		temp.url = url;
		temp.load();
		
		return asset;
	}
	
	public static function loadSWFAsset(url:String, mode:String, onComplete:Function = null, onError:Function = null):Asset
	{
		var cache:SWFCache = swfs[url];
		var asset:Asset = createAsset(TYPE_SWF, onComplete, onError);
		SWF(asset).mode = mode;
		asset.url = url;
		
		if (mode == SWF.SINGLE)
		{
			asset.load();
			return asset;
		}
		
		if (cache)
		{
			cache.addQueen(asset);
			
			TweenMax.to(tweener, 0.02, {onCompleteParams: [ cache ], 
										onComplete: function():void{
											if (cache.isLoaded)
											{
												cache.complete();
											}
											else if (cache.isError)
											{
												cache.error();
											}
										}});
			
			return asset;
		}
		
		cache = new SWFCache();
		cache.id = url;
		swfs[cache.id] = cache;
		
		cache.addQueen(asset);
		
		var temp:SWF = createAsset(TYPE_SWF, swfLoadedHandler, swfLoadFailHandler) as SWF;
		temp.url = url;
		temp.mode = mode;
		temp.load();
		
		return asset;
	}
	
	public static function createAsset(type:String, onComplete:Function = null, onError:Function = null):Asset
	{
		var asset:Asset;
		switch (type)
		{
			case TYPE_BITMAP:
				asset = new Image();
				break;
			case TYPE_SWF:
				asset = new SWF();
				break;
		}
		asset.id = UIDUtil.createUID();
		asset.onComplete = onComplete;
		asset.onError = onError;
		return asset;
	}
	
	private static function bitmapLoadedHandler(asset:Asset):void
	{
		var cache:BitmapCache = bitmaps[asset.url];
		cache.bitmapData = BitmapUtil.getBitmapData(asset.content);
		cache.complete();
	}
	
	private static function bitmapLoadFailHandler(asset:Asset):void
	{
		var cache:BitmapCache = bitmaps[asset.url];
		cache.error();
	}
	
	private static function swfLoadedHandler(asset:SWF):void
	{
		var cache:SWFCache = swfs[asset.url];
		cache.appDomain = asset.appDomain;
		cache.complete();
	}
	
	private static function swfLoadFailHandler(asset:Asset):void
	{
		var cache:SWFCache = swfs[asset.url];
		cache.error();
	}
}
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.Dictionary;

import framework.view.components.graphics.Asset;
import framework.view.components.graphics.asset_ns;

class BitmapCache
{
	public function BitmapCache()
	{		
	}
	
	public var id:String;
	
	public var assets:Dictionary = new Dictionary(true);
	
	private var _isError:Boolean = false;

	public function get isError():Boolean
	{
		return _isError;
	}
	
	private var _bitmapData:BitmapData;
	
	public function get bitmapData():BitmapData
	{
		return _bitmapData;
	}
	
	public function set bitmapData(value:BitmapData):void
	{
		_bitmapData = value;
		_isError = false;
	}
	
	public function get isLoaded():Boolean
	{
		return bitmapData ? true : false;
	}
	
	public function addQueen(asset:Asset):void
	{
		assets[asset.id] = asset;
	}
	
	public function removeQueen(asset:Asset):void
	{
		delete assets[asset.id];
	}
	
	public function complete():void
	{
		for each (var asset:Asset in assets)
		{
			asset.asset_ns::content = new Bitmap(bitmapData.clone());
			if (asset.onComplete != null)
			{
				asset.onComplete(asset);
			}
		}
		assets = new Dictionary(true);
	}
	
	public function error():void
	{
		_isError = true;
		for each (var asset:Asset in assets)
		{
			if (asset.onError != null)
			{
				asset.onError(asset);
			}
		}
		assets = new Dictionary(true);
	}
	
}



import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.Dictionary;

import framework.view.components.graphics.Asset;
import framework.view.components.graphics.asset_ns;
import flash.system.ApplicationDomain;
import framework.view.components.graphics.SWF;

class SWFCache
{
	public function SWFCache()
	{		
	}
	
	public var id:String;
	
	public var assets:Dictionary = new Dictionary(true);
	
	private var _isError:Boolean = false;
	
	public function get isError():Boolean
	{
		return _isError;
	}
	
	private var _appDomain:ApplicationDomain;
	
	public function get appDomain():ApplicationDomain
	{
		return _appDomain;
	}
	
	public function set appDomain(value:ApplicationDomain):void
	{
		_appDomain = value;
		_isError = false;
	}
	
	public function get isLoaded():Boolean
	{
		return appDomain ? true : false;
	}
	
	public function addQueen(asset:Asset):void
	{
		assets[asset.id] = asset;
	}
	
	public function removeQueen(asset:Asset):void
	{
		delete assets[asset.id];
	}
	
	public function complete():void
	{
		for each (var asset:SWF in assets)
		{
			asset.asset_ns::appDomain = appDomain;
			if (asset.onComplete != null)
			{
				asset.onComplete(asset);
			}
		}
		assets = new Dictionary(true);
	}
	
	public function error():void
	{
		_isError = true;
		for each (var asset:Asset in assets)
		{
			if (asset.onError != null)
			{
				asset.onError(asset);
			}
		}
		assets = new Dictionary(true);
	}
	
}